﻿using Flurl.Http;
using NPOI.SS.Formula.Functions;
using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.DTO.tenPay;
using Pay.IService;
using Pay.TO;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pay.Service.Pay
{
    public class TenSubPayService : ServiceBase2, IPayService, IDisposable
    {
        private IMerchantService _iMerchantService;
        private IChargeService _iChargeService;
        private IBillService _iBillService;
        private IPayHtmlService _iPayHtmlService;
        private ISettingService _iSettingService;
        private TenSubPaySign _tenSubPaySign;

        public TenSubPayService(IUnitOfWork iUnitOfWork, IMerchantService merchantService,
                                IChargeService chargeService, IBillService billService,
                                IPayHtmlService payHtmlService, ISettingService settingService) : base(iUnitOfWork)
        {
            _tenSubPaySign = new TenSubPaySign();
            _iMerchantService = merchantService;
            _iChargeService = chargeService;
            _iBillService = billService;
            _iPayHtmlService = payHtmlService;
            _iSettingService = settingService;
        }

        public Task<transfer_result> AgencyFund(apply_receive model)
        {
            throw new NotImplementedException();
        }

        public Task<certify_verify_result> CertifyVerify(certify_verify model)
        {
            throw new NotImplementedException();
        }

        public int DealItp(long id)
        {
            throw new NotImplementedException();
        }

        public Task<gateway_pay_result> GatewayPay(gateway_pay_model model)
        {
            throw new NotImplementedException();
        }

        public List<type_setting> GatewayPayBank()
        {
            throw new NotImplementedException();
        }

        public Task<pay_notity> GatewayPayQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayPayRefund(refund_model model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayRefundQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model_sms model)
        {
            throw new NotImplementedException();
        }

        public Task<int> ItpToFile(DateTime create_date)
        {
            throw new NotImplementedException();
        }

        public Task<mall_result> MallPay(mall_model obj)
        {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantModify(long bind_id, string settle_type, PayChannel channel = PayChannel.None)
        {
            throw new NotImplementedException();
        }

        public async Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt)
        {
            dto.reg_merchant_no = "123456";
            return await ApiResultToJson.JsonAsync<merchant_register_result>("", new merchant_register_result { merchant_no = dto.reg_merchant_no });
        }

        public Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type, PayChannel channel = PayChannel.None)
        {
            throw new NotImplementedException();
        }

        public Task<native_result> NativePay(native_model obj)
        {
            throw new NotImplementedException();
        }

        public async Task<string> Notify(string merchant_no, string order_no)
        {
            string result = string.Empty;
            charge_dto order = _iChargeService.Get(merchant_no, order_no);
            try
            {
                var data = new pay_notity
                {
                    tran_amount = ((int)(order.order_amount * 100)).ToString(),
                    order_no = order.order_no,
                    transaction_no = order.pay_info.transaction_no,
                    pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
                    status = (order.status == ChargeStatus.Finish ? 1 : 2)
                };
                data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
                if (string.IsNullOrEmpty(order.notify)) return "OK";
                var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                result = notify_result.data;
                var log = IocHelper.Get<ILogHelper>("info");
                log.Info(order.order_no + ":" + notify_result.ToJson());
            }
            catch (Exception ex)
            {
                var log = IocHelper.Get<ILogHelper>("info");
                log.Error("订单通道查询异常:" + order.order_no);
                string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
                                , ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
                log.Error(message);
            }
            return result;
        }

        public Task<string> NotifyTransfer(string merchant_no, string order_no)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<quick_pay_result> QuickPay(quick_pay_model model)
        {
            var binder = _iMerchantService.Get(model.bind_no);
            var setting = _iSettingService.Get();
            string pay_code = model.pay_code;
            model.settle_type = "T0";
            var binder_payments = _iMerchantService.GetPayments(binder.id);
            var payment = binder_payments.FirstOrDefault(c => c.payment.channel == model.pay_channel);
            var settle = payment.settles.First(c => c.settle_type == model.settle_type && c.code == pay_code);
            if (model.settle_fee / 100M != settle.settle)
                return ApiResultToJson.Json<quick_pay_result>("结算费与商户进件的结算费不同");
            if (model.fee != settle.fee)
                return ApiResultToJson.Json<quick_pay_result>("费率与商户进件的费率不同");
            if (model.pay_fee_amount != (int)Math.Ceiling(decimal.Parse(model.tran_amount) * model.fee))
                return ApiResultToJson.Json<quick_pay_result>("实扣费率金额不正确");
            var merchantRegister = _iMerchantService.GetRegister(model.id_card, model.pay_channel);
            if (merchantRegister != null)
            {
                var paymentData = new payment_data
                {
                    account_name = merchantRegister.account_name,
                    account_no = merchantRegister.account_no,
                    id_card = merchantRegister.id_card,
                    mobile = merchantRegister.mobile
                };
                var id = Guid.NewGuid().ToString("N");
                var notify = "http://pay.timebiz.cn/pay/ten_sub_pay_notify/" + id;
                decimal amt = decimal.Parse(model.tran_amount) / 100M;
                var cardValid = model.vaild;
                if (cardValid.Length == 4)
                {
                    cardValid = cardValid.Substring(cardValid.Length - 2) + cardValid.Substring(0, 2);
                }

                List<string> cityLists = new List<string>
                {
                    "北京市",
                    "上海市",
                    "天津市",
                    "厦门市",
                    "衡阳市",
                    "重庆市",
                    "石家庄市",
                    "唐山市",
                    "邯郸市",
                    "衡水市"
                };
                int randIndex = new Random().Next(0, 9);

                var pay_sub_req = new ten_sub_pre_pay
                {
                    orderNo = DtoHelper.GenerateOrderNumber(),
                    reqNo = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    merchantId = TenSubPaySign.mchid,
                    tradeName = "酒店预订",
                    tradeTime = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    amount = model.tran_amount,
                    custAccountCreditOrDebit = "2",
                    custCardValidDate = _tenSubPaySign.encrypt(cardValid),
                    custCardCvv2 = _tenSubPaySign.encrypt(model.cvv2),
                    custBankAccountNo = _tenSubPaySign.encrypt(model.account_no),
                    custBindPhoneNo = _tenSubPaySign.encrypt(model.mobile),
                    custName = _tenSubPaySign.encrypt(model.account_name),
                    custID = _tenSubPaySign.encrypt(model.id_card),
                    outCardNo = _tenSubPaySign.encrypt(merchantRegister.account_no),
                    outCardPhone = model.mobile,
                    settleFee = model.settle_fee.ToString(),
                    payRate = (model.fee * 100).ToString("0.0"),
                    paymentNotifyURL = model.front_notify,
                    notifyUrl = notify,
                    sourceIP = "60.205.220.14",
                    rateAmount = ((int)(((amt * model.fee + settle.settle).RoundEx(2)) * 100)).ToString(),
                    //cityName = cityLists[randIndex]
                    cityName = string.IsNullOrEmpty(model.location) ? cityLists[randIndex] : model.location
                };
                var resultApi = await _tenSubPaySign.PayGateway<ten_sub_pre_pay_res>(pay_sub_req, "/payapi/treatyCollectApply");
                if (resultApi != null)
                {
                    if (resultApi.errorCode == "0000")
                    {
                        paymentData.amount = pay_sub_req.amount;
                        paymentData.rateAmount = pay_sub_req.rateAmount;
                        paymentData.data = resultApi.data;
                        var charge = _iChargeService.AddByQuickPay(model);
                        var ok = _iPayHtmlService.Save(new pay_html_dto { id = id, html = paymentData.ToJson(), merchant_no = model.merchant_no, order_no = model.order_no, charge = charge.ToJson(), pay_type = "30" });
                        if (ok)
                        {
                            return ApiResultToJson.Json("鉴权成功，待确认支付", new quick_pay_result
                            {
                                order_no = model.order_no,
                                protocol_no = "",
                                request_url = "",
                                pay_time = DateTime.Now,
                                transaction_no = "",
                                status = 3
                            });
                        }
                        else
                            return ApiResultToJson.Json<quick_pay_result>("支付页面加载失败");
                    }
                    else
                    {
                        return ApiResultToJson.Json<quick_pay_result>(resultApi.failureDetails);
                    }
                }
            }

            return ApiResultToJson.Json<quick_pay_result>("异常支付");
        }
        /// <summary>
        /// 确认支付
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<quick_pay_result> QuickPay(quick_sms_model model)
        {
            var payHtml = _iPayHtmlService.Get(model.merchant_no, model.order_no);
            var register = payHtml.html.ToObject<payment_data>();
            if (!string.IsNullOrEmpty(register.data.orderNo) && !string.IsNullOrEmpty(register.data.smsSeq))
            {
                var pay_confirm_req = new ten_sub_pay
                {
                    orderNo = register.data.orderNo,
                    merchantId = TenSubPaySign.mchid,
                    smsCode = model.sms_code,
                    smsSeq = register.data.smsSeq
                };
                var resultApi = await _tenSubPaySign.PayGateway<ten_sub_pay_res>(pay_confirm_req, "/payapi/treatyCollectApplyConfirm");
                if (resultApi != null)
                {
                    if (resultApi.errorCode == "0000" && resultApi.data.status == "3")
                    {
                        return ApiResultToJson.Json("支付成功", new quick_pay_result { status = 3 });
                    }
                    else
                    {
                        return ApiResultToJson.Json<quick_pay_result>(resultApi.failureDetails);
                    }
                }
            }
            return ApiResultToJson.Json<quick_pay_result>("异常支付");
        }

        public async Task<pay_notity> QuickPayQuery(refund_model_query model)
        {
            var pay_html = _iPayHtmlService.Get(model.order_no);
            var pay_result = new pay_notity();
            var paySign = new TenSubPaySign();
            if (pay_html == null) return pay_result;
            var payment = pay_html.html.ToObject<payment_data>();
            var log = IocHelper.Get<ILogHelper>("info");
            log.Info("腾付通分公司重新代付出款");
            var pay_notify = new ten_sub_payment();
            pay_notify.orderNo = DtoHelper.GenerateOrderNumber();
            pay_notify.merchantId = TenSubPaySign.mchid;
            pay_notify.amount = payment.amount;
            pay_notify.notifyUrl = "http://pay.timebiz.cn/ten_sub_payment_notify/" + pay_html.merchant_no;
            pay_notify.tradeName = "酒店预订";
            pay_notify.tradeTime = DateTime.Now.ToString("yyyyMMddHHmmss");
            pay_notify.custBankAccountNo = paySign.encrypt(payment.account_no);
            pay_notify.custPhone = paySign.encrypt(payment.mobile);
            pay_notify.custID = paySign.encrypt(payment.id_card);
            pay_notify.custName = paySign.encrypt(payment.account_name);
            pay_notify.sourceIP = "60.205.220.14";
            var paymentResult = await paySign.PayGateway<ten_payment_res>(pay_notify, "/payapi/singlePrePayment");
            if (paymentResult != null)
            {
                if (paymentResult.data.status == "3")
                {
                    log.Info("请求代付接口成功");
                    pay_result.result_code = 1000;
                    pay_result.status = 1;
                }
            }
            return pay_result;
        }

        public Task<refund_result> QuickPayRefund(refund_model model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> QuickPayRefundQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model)
        {
            throw new NotImplementedException();
        }

        public Task<quota_result> Quota(string merchant_no, string busiType)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> ReTransfer(long id)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransfer(long id)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> Transfer(apply_transfer model)
        {
            throw new NotImplementedException();
        }

        public Task<batch_transfer_result> Transfer(batch_transfer model)
        {
            throw new NotImplementedException();
        }

        public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id)
        {
            throw new NotImplementedException();
        }

        public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TransferQuery(transfer_query model)
        {
            throw new NotImplementedException();
        }
    }
}
